/*clase que trata un arreglo vectorial de int como un arreglo vectorial de bytes
 *
 */



package Modelo;

public class ByteDesdetArray {

    private boolean littleEndian;
    public static final ByteDesdetArray LITTLEENDIAN = new ByteDesdetArray(true);
    public static final ByteDesdetArray BIGENDIAN = new ByteDesdetArray(false);

    public ByteDesdetArray(boolean littleEndian) {
        this.littleEndian = littleEndian;
    }

    public byte getByte(int[] array, int ubicacion) {
        if ((ubicacion / 4) >= array.length) {
            throw new ArrayIndexOutOfBoundsException("Ubicacion = " + ubicacion + ", numero de bytes = " + (array.length * 4));
        }

        int elEntero = ubicacion / 4; // cajon
        int elByte = ubicacion % 4; // resto


        //invertir los bytes para simular little endian
        if (littleEndian) {
            elByte = 3 - elByte;
        }


        if (elByte == 0) {
            return (byte) ((array[elEntero] & 0x000000FF) >> 0);
        } else if (elByte == 1) {
            return (byte) ((array[elEntero] & 0x0000FF00) >> 8);
        } else if (elByte == 2) {
            return (byte) ((array[elEntero] & 0x00FF0000) >> 16);
        } else if (elByte == 3) {
            return (byte) ((array[elEntero] & 0xFF000000) >> 24);
        }

        return 0;
    }

    //Esta funcion es usada para insertar un byte en una posición especifica. Trabaja en little endian
    public int[] insertarByte(int[] intBuffer, int ubicacion, byte b) {
        //Se obtiene la ubicación
        int elEntero = ubicacion / 4;
        int elByte = ubicacion % 4;

        //Si no usamos little endian
        if (littleEndian == false) {
            elByte = 3 - elByte;
        }

        int reemplazaEntero = intBuffer[elEntero];

        // Nueva variable pq B esta en byte
        int newByte = b << (8 * elByte);

        if (elByte == 0) {
            reemplazaEntero &= 0xFFFFFF00;
        } else if (elByte == 1) {
            reemplazaEntero &= 0xFFFF00FF;
        } else if (elByte == 2) {
            reemplazaEntero &= 0xFF00FFFF;
        } else if (elByte == 3) {
            reemplazaEntero &= 0x00FFFFFF;
        }

        reemplazaEntero = reemplazaEntero | newByte;

        intBuffer[elEntero] = reemplazaEntero;

        return intBuffer;

    }

    public byte[] getByteArray(int[] array) {
        byte[] nuevoArreglo = new byte[array.length * 4];

        int pos = 0;
        for (int i = 0; i < array.length; i++) {
            if (littleEndian) {
                nuevoArreglo[pos++] = (byte) ((array[i] >> 0) & 0xFF);
                nuevoArreglo[pos++] = (byte) ((array[i] >> 8) & 0xFF);
                nuevoArreglo[pos++] = (byte) ((array[i] >> 16) & 0xFF);
                nuevoArreglo[pos++] = (byte) ((array[i] >> 24) & 0xFF);
            } else {
                nuevoArreglo[pos++] = (byte) ((array[i] >> 24) & 0xFF);
                nuevoArreglo[pos++] = (byte) ((array[i] >> 16) & 0xFF);
                nuevoArreglo[pos++] = (byte) ((array[i] >> 8) & 0xFF);
                nuevoArreglo[pos++] = (byte) ((array[i] >> 0) & 0xFF);
            }
        }

        return nuevoArreglo;
    }

    public byte[] getByteArray(int entero) {
        int[] temp = new int[1];
        temp[0] = entero;
        return getByteArray(temp);
    }
}
